<?php

class ApiAction extends Action
{
    private $resultData= array();

    //http错误返回码
    static $_status = array(
        // Informational 1xx
        100 => 'Continue',
        101 => 'Switching Protocols',
        // Success 2xx
        200 => 'OK',
        201 => 'Created',
        202 => 'Accepted',
        203 => 'Non-Authoritative Information',
        204 => 'No Content',
        205 => 'Reset Content',
        206 => 'Partial Content',
        // Redirection 3xx
        300 => 'Multiple Choices',
        301 => 'Moved Permanently',
        302 => 'Moved Temporarily ',  // 1.1
        303 => 'See Other',
        304 => 'Not Modified',
        305 => 'Use Proxy',
        // 306 is deprecated but reserved
        307 => 'Temporary Redirect',
        // Client Error 4xx
        400 => 'Bad Request',
        401 => 'Unauthorized',
        402 => 'Payment Required',
        403 => 'Forbidden',
        404 => 'Not Found',
        405 => 'Method Not Allowed',
        406 => 'Not Acceptable',
        407 => 'Proxy Authentication Required',
        408 => 'Request Timeout',
        409 => 'Conflict',
        410 => 'Gone',
        411 => 'Length Required',
        412 => 'Precondition Failed',
        413 => 'Request Entity Too Large',
        414 => 'Request-URI Too Long',
        415 => 'Unsupported Media Type',
        416 => 'Requested Range Not Satisfiable',
        417 => 'Expectation Failed',
        // Server Error 5xx
        500 => 'Internal Server Error',
        501 => 'Not Implemented',
        502 => 'Bad Gateway',
        503 => 'Service Unavailable',
        504 => 'Gateway Timeout',
        505 => 'HTTP Version Not Supported',
        509 => 'Bandwidth Limit Exceeded'
    );

    protected $uid;

    protected function _initialize() {
        $this->auth();
    }


//    function __construct()
//    {
//        parent::__construct();
//
//        $this->auth();
//    }

    /**
     * 校验入口
     * 从请求中提取安全数据
     */
    private function auth()
    {
        $method = $_SERVER['REQUEST_METHOD'];

        if(strtolower($method) == 'get'){   //是get请求
            $secret = empty($_GET['secret'])?'':$_GET['secret'];
            $uid = empty($_GET['uid'])?0:$_GET['uid'];
            $this->uid = $uid;
            //$time = empty($_GET['time'])?0:$_GET['time'];
        } else if(strtolower($method) == 'post') {  //是post请求
            $secret = empty($_POST['secret'])?'':$_POST['secret'];
            $uid = empty($_POST['uid'])?0:$_POST['uid'];
            $this->uid = $uid;
            //$time = empty($_POST['time'])?0:$_POST['time'];
        } else {    //其他类型请求
            $this->rest('', 11, 500);
        }

        //检查该用户是否有该接口访问权限
        $this->checkOpenApi($uid);

        $this->checkSafe($secret, $uid);
    }


    /**
     * 进行安全校验
     *
     * @param $secret
     * @param $uid
     * @param $time
     */
    private function checkSafe($secret, $uid)
    {
        $token = '';    //口令

        if ($uid == 0){ //没有录入使用默认口令
            $secret_true = C('nomerToken');
        } else { //使用用户自身唯一口令
            $user = M('Token');
            $tokenArr = $user->field('token_value,token_time')->where("user_id = {$uid}")->find();

            $token_value = $tokenArr['token_value'];
            $token_time = $tokenArr['token_time'];
            $effect_time = $token_time+3600*24*15;
            if (time()>$effect_time){
                $this->rest('',15);
            }

            $secret_true = md5($token_time.$token_value.$uid);
        }




        if($secret_true != $secret){    //没有通过安全校验
            $this->rest('', 14, 401);
        }

    }


    /**
     * 接口开放检测
     *
     * @param $uid
     */
    private function checkOpenApi($uid)
    {
        $api = trim(__ACTION__, '/');

        $serverApi = C('api');  //api接口和说明数组

        $serverApi_key = array_keys($serverApi['open']);
        $serverApi_key = array_merge( $serverApi_key, array_keys($serverApi['notopen']));   //接口数组



        if (!in_array($api, $serverApi_key)){ //不是被允许的接口
            $this->rest('', 12, 404);
        } else if($uid == 0 && !in_array($api, array_keys($serverApi['open']))){    //没有录入用户不能使用该接口
            $this->rest('', 13, 401);
        }
    }


    /**
     * rest数据返回
     *
     * @param $data 返回的数据
     * @param string $errorCode 自定义错误码
     * @param int $httpCode 定义的http错误码
     */
    protected function rest($data, $errorCode=1, $httpCode='')
    {
        if ($data == ''){
            $data = array();
        }

        $code = $this->returnMessage($errorCode, $httpCode);

        $this->resultData['datas'] = $data;
        $this->returnClient($this->resultData, $code);
    }

    /**
     * 组织返回的提示信息
     *
     * @param $errorCode 错误提示码
     * @param $httpCode http错误码
     * @return int|string 返回错误码
     */
    private function returnMessage($errorCode, $httpCode)
    {
        //errorcode 等于0000
        if($errorCode == 1){
            $code = '200';
        }else if($errorCode != 1){ //errprcode 不等于0000
            $code =  ($httpCode == '')?404:$httpCode;
        }

        $this->resultData['state'] = $errorCode;
        $message = C('errorMsg')[$errorCode];

        if($message == null || $message == ''){
            $code = 500;
            $this->resultData['msg'] = "没有定义{$errorCode}的返回信息，请提示服务端工程师修改";
            $this->resultData['datas'] = '';
        }else {
            $this->resultData['state'] = $errorCode;
            $this->resultData['msg'] = $message;
        }

        //返回错误
        return $code;
    }

    /**
     * 将组织好的数据返回给客户端
     *
     * @param $data
     */
    private function returnClient($data, $code){
        //header("HTTP/1.1 ".$code." ".self::$_status[$code]);
        header('Content-Type: application/json;charset=utf-8');

//        $jsonStr = json_encode($data, JSON_UNESCAPED_UNICODE);
        $jsonStr = json_encode($data);
        exit($jsonStr);
    }

    /**
     * 请求错误方法返回
     */
    protected function _empty()
    {
        $this->rest('', 12, 404);
    }
}
